package org.gpp.proj1.bone;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

import com.jme.math.Quaternion;

public class BoneFileParser {

	/**
	 * Reads the keyframes from a file
	 * 
	 * @param keyframeFile The path to the keyframe file
	 * @throws FileNotFoundException If the keyframe file wasn't found
	 * @throws InvalidKeyframeFileException 
	 */
	public static void loadKeyframes( String keyframeFile, Bone bone ) throws FileNotFoundException, InvalidKeyframeFileException {

		assert keyframeFile != null : "Cannot load a keyframe file with a null name";
		assert bone != null : "Cannot load a keyframe file to a null bone";

		Scanner scanner = new Scanner( new FileInputStream( keyframeFile ) );

		while( scanner.hasNext() ) {
			String rawLine = scanner.nextLine();

			if( isComment(rawLine) || rawLine.trim().equals( "" ) ) {
				continue;
			}

			String[] line = rawLine.trim().split( " +" );

			if( line[0].equals( "keyframe" ) && line[1].equals( bone.getName() ) ) {
				
				if( line.length < 7 ) {
					throw new InvalidKeyframeFileException( "The line isn't valid : Not sufficient parameters" );
				}
				
				float[] angles = { (float)Math.toRadians( Float.parseFloat( line[2] ) ),
						(float)Math.toRadians( Float.parseFloat( line[3] ) ),
						(float)Math.toRadians( Float.parseFloat( line[4] ) ) };
				
				Quaternion keyframeAngle = new Quaternion( angles );
				keyframeAngle.normalize();

				float keyframeLength = Float.parseFloat( line[5] );
				float keyframeWidth = Float.parseFloat( line[6] );

				bone.addKeyframe( keyframeAngle, keyframeLength, keyframeWidth );
				
			} else if( line[0].equals( "animation" ) && line[1].equals( bone.getName() ) ) {
				boolean loops = line.length >= 7 && line[5].equals( "loops" );
				
				if( !loops && line.length < 5  ) {
					throw new InvalidKeyframeFileException( "The line isn't valid : Not sufficient parameters" );
				}
				
				KeyframeInterval interval = new KeyframeInterval( Integer.parseInt( line[3] ), Integer.parseInt( line[4] ) );
				
				if( loops ) {
					bone.addAnimation( new Animation( line[2], interval, loops, Integer.parseInt( line[6] ) ) );
				} else {
					bone.addAnimation( new Animation( line[2], interval ) );
				}
			}
		}
	}

	/**
	 * @param line
	 * @return <code>true</code> if <i>line</i> is a comment and shall be ignored
	 */
	private static boolean isComment( String line ) {

		assert line != null : "Cannot check null lines";

		return line.startsWith( "//" ) || line.startsWith( "#" );
	}
}
